import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.lines import Line2D

# Ensure you have at least three unique points for each front
front1 = np.array([[1, 1, 1], [2, 1, 0], [0, 2, 0]])  # First front points (3 unique)
front2 = np.array([[1, 2, 2], [2, 2, 1], [3, 1, 1]])  # Second front points (3 unique)
front3 = np.array([[1, 3, 3], [3, 2, 2], [4, 4, 4]])  # Third front points (3 unique)

# Create a 3D plot
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# Plot the surfaces for each front
surf1 = ax.plot_trisurf(front1[:, 0], front1[:, 1], front1[:, 2], color='red', alpha=0.7)
surf2 = ax.plot_trisurf(front2[:, 0], front2[:, 1], front2[:, 2], color='green', alpha=0.7)
surf3 = ax.plot_trisurf(front3[:, 0], front3[:, 1], front3[:, 2], color='blue', alpha=0.7)

# Annotate the points for the first front
for i, point in enumerate(front1):
    ax.text(point[0], point[1], point[2], f'A{i+1} ({point[0]}, {point[1]}, {point[2]})', size=10, color='red')

# Annotate the points for the second front
for i, point in enumerate(front2):
    ax.text(point[0], point[1], point[2], f'B{i+1} ({point[0]}, {point[1]}, {point[2]})', size=10, color='green')

# Annotate the points for the third front
for i, point in enumerate(front3):
    ax.text(point[0], point[1], point[2], f'C{i+1} ({point[0]}, {point[1]}, {point[2]})', size=10, color='blue')

# Set labels
ax.set_xlabel('h1')
ax.set_ylabel('h2')
ax.set_zlabel('h3')
ax.set_title('3D Pareto Fronts')

# Create custom legend handles
legend_elements = [
    Line2D([0], [0], marker='o', color='w', markerfacecolor='red', markersize=10, label='Front 1'),
    Line2D([0], [0], marker='o', color='w', markerfacecolor='green', markersize=10, label='Front 2'),
    Line2D([0], [0], marker='o', color='w', markerfacecolor='blue', markersize=10, label='Front 3')
]

# Show legend
ax.legend(handles=legend_elements)

# Set ticks to integers
ax.set_xticks(np.arange(0, 5, 1))  # x-axis ticks
ax.set_yticks(np.arange(0, 5, 1))  # y-axis ticks
ax.set_zticks(np.arange(0, 5, 1))  # z-axis ticks

# Show plot
plt.show()
